package com.solo.quartz.service.inner;

import com.solo.quartz.api.entity.QrtzJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Component;

/**
 * 定人任务管理
 * @author 十一
 * @since 2024/08/19
 * 人生若只如初见，何事秋风悲画扇
 **/
@Slf4j
@Component
public class QuartzManage {

    @Resource
    private Scheduler scheduler;

    /**
     * 新增作业
     * @param qrtzJob qrtz作业
     */
    public void createJob(QrtzJob qrtzJob) {
        try {
            JobKey jobKey = getJobKey(qrtzJob);
            TriggerKey triggerKey = getTriggerKey(qrtzJob);
            // 构建任务
            JobDetail jobDetail = JobBuilder.newJob(QuartzRecord.class).withIdentity(jobKey).build();
            // 构建Cron调度器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(qrtzJob.getCron()).withMisfireHandlingInstructionDoNothing();
            // 任务触发器
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            jobDetail.getJobDataMap().put("scheduleJob", qrtzJob);
            scheduler.scheduleJob(jobDetail, trigger);
            // 状态校验
            stopJob(qrtzJob);
        } catch (SchedulerException e) {
            log.error("新增定时任务失败，详细信息： {}", e.getMessage());
        }
    }

    /**
     * 更新作业
     * @param qrtzJob qrtz作业
     */
    public void updateJob(QrtzJob qrtzJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(qrtzJob);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            // 构建Cron调度器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(qrtzJob.getCron()).withMisfireHandlingInstructionDoNothing();
            // 任务触发器
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            trigger.getJobDataMap().put("scheduleJob", qrtzJob);
            scheduler.rescheduleJob(triggerKey, trigger);
            // 状态校验
            stopJob(qrtzJob);
        } catch (SchedulerException e) {
            log.error("修改定时任务失败，详细信息： {}", e.getMessage());
        }
    }

    /**
     * 停止作业
     * @param qrtzJob qrtz作业
     */
    public void stopJob(QrtzJob qrtzJob) {
        try {
            if (qrtzJob.getStatus() != 1) {
                scheduler.pauseJob(getJobKey(qrtzJob));
            }
        } catch (SchedulerException e) {
            log.error("暂停定时任务失败，详细信息： {}", e.getMessage());
        }
    }

    /**
     * 恢复作业
     * @param qrtzJob qrtz作业
     */
    public void resumeJob(QrtzJob qrtzJob) {
        try {
            scheduler.resumeJob(getJobKey(qrtzJob));
        } catch (SchedulerException e) {
            log.error("恢复定时任务失败，详细信息： {}", e.getMessage());
        }
    }

    /**
     * 立即运行一次作业
     * @param qrtzJob qrtz作业
     */
    public void runJob(QrtzJob qrtzJob) {
        try {
            JobDataMap dataMap = new JobDataMap();
            dataMap.put("scheduleJob", qrtzJob);
            this.scheduler.triggerJob(getJobKey(qrtzJob), dataMap);
        } catch (SchedulerException e) {
            log.error("立即执行一次定时任务失败，详细信息： {}", e.getMessage());
        }
    }

    public void deleteJob(QrtzJob qrtzJob) {
        try {
            // 停止触发器
            scheduler.pauseTrigger(getTriggerKey(qrtzJob));
            // 移除触发器
            scheduler.unscheduleJob(getTriggerKey(qrtzJob));
            scheduler.deleteJob(getJobKey(qrtzJob));
        } catch (SchedulerException e) {
            throw new RuntimeException("deleteJob Fail", e);
        }
    }

    /**
     * 获取定时任务的唯一key
     * @param qrtzJob 作业
     * @return {@link JobKey }
     */
    public JobKey getJobKey(QrtzJob qrtzJob) {
        return JobKey.jobKey(qrtzJob.getName(), qrtzJob.getGroup());
    }

    /**
     * 获取定时任务触发器cron的唯一key
     * @param qrtzJob 作业
     * @return {@link TriggerKey }
     */
    public TriggerKey getTriggerKey(QrtzJob qrtzJob) {
        return TriggerKey.triggerKey(qrtzJob.getName(), qrtzJob.getGroup());
    }

}
